/*
* Copyright 2009 NOR_/D Labs <http://labs.nortd.com>
*
* This file is part of SceneExpression.
* SceneExpression is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License 
* as published by the Free Software Foundation, either version 3 of 
* the License, or (at your option) any later version. For details
* see <http://www.gnu.org/licenses/>.
*
* * *
* 
*/

#include <sx/SliderWidget.h>

using namespace sx;


// SliderNob
//

SliderNob::SliderNob( SliderWidget* slider ) {
    _slider = slider;
    _label = new  osgText::Text;
    _geode->addDrawable( _label.get() );
    _defaultTypeface = "TitilliumText400wt.ttf";
    _label->setAlignment(osgText::Text::CENTER_CENTER);
    _label->setFontResolution(32,32);
    _value = 0.0f;
    _valueMin = -1.0f;
    _valueMax = 1.0f;
    _buttonPressBorderColor.set(1.0f, 1.0f, 1.0f, 1.0f);
}


void SliderNob::setValue( float value ) {
    if( value != _value ) {
        osg::clampBetweenRange(value, _valueMin, _valueMax, "value in SetValue(...)");
        _value = value;
        float xpos = rangemap(value, _valueMin, _valueMax, 0.5f*_width, (_slider->getWidth())-0.5f*_width);
        setX(xpos);
        
        // delegate on-value-change to registered handlers
        for( unsigned int i=0; i<_slider->getEventHandlers().size(); i++) {
            _slider->getEventHandlers()[i]->widgetSlider( *_slider );
        }
    }
}
float SliderNob::getValue() {
    return _value;
}

void SliderNob::setLabelColor( float r, float g, float b, float a ) {
    _label->setColor(osg::Vec4(r,g,b,a));
}


void SliderNob::reshape() {
    _backgroundVertices->clear();
    //setBackgroundColor(0.2f, 0.0f, 0.0f, 0.5f);
    addRoundedRect(0.0f, 0.0f, _width, _height, 6.0f, _backgroundVertices.get());
    _backgroundDrawArray->setCount(_backgroundVertices->size());
    //setBorderColor(0.2f, 0.0f, 0.0f, 0.5f);
    _borderDrawArray->setCount(_backgroundVertices->size());
    
    //label
    setLabelColor(1.0f, 1.0f, 1.0f, 1.0f);
    _label->setFont(_defaultTypeface);
    _label->setText(getName());
    _label->setPosition(osg::Vec3(_width/2.0f, _height/2.0f, 0.0f));
    _label->setCharacterSize(16.0f);
    _label->setMaximumWidth(_width);
    _label->setMaximumHeight(_height);        
}
    
bool SliderNob::touchDown( Touch& touch ) {
    _buttonPressBorderColorTemp = getBorderColor();
    setBorderColor(_buttonPressBorderColor);  
    return true;
}
bool SliderNob::touchMove( Touch& touch ) {
    if( isDragging(touch) ) {
        float posx = getX();
        posx += getWorldDragDelta(touch)[0];
        osg::clampBetweenRange(posx, 0.5f*_width, (_slider->getWidth())-0.5f*_width, "slider-value");        
        setValue(rangemap(posx, 0.5f*_width, (_slider->getWidth())-0.5f*_width, _valueMin, _valueMax));
    }
    return true;
}
bool SliderNob::touchUp( Touch& touch ) {
    setBorderColor(_buttonPressBorderColorTemp);
    return true;
} 




// Slider
//

SliderWidget::SliderWidget() {
    
    //state
    disableLighting();
    disableDepthTest();
    enableBlending();     
    
    
    // setup slider nob geometry
    _nob = new SliderNob(this);
    addChild(_nob);

    setPosition(0.0f, 0.0f, 0.0f);
    setShape(100, 25); 
}


void SliderWidget::setValue( float value ) {
    _nob->setValue(value);
}
float SliderWidget::getValue() { return _nob->_value; }
void SliderWidget::setValueMin( float min ) { _nob->_valueMin = min; }
void SliderWidget::setValueMax( float max ) { _nob->_valueMax = max; }


void SliderWidget::reshape() {
    // define background geometry
    _backgroundVertices->clear();
    setBackgroundColor(0.5f, 0.5f, 0.5f, 0.7f);
    addRoundedRect(0.0f, 0.5*_height-7.f, _width, 14.f, 7.f, _backgroundVertices.get());
    _backgroundDrawArray->setCount(_backgroundVertices->size());
    //setPivot(_width/2.f, _height/2.f, 0.f);
    _borderDrawArray->setCount(_backgroundVertices->size());
    
    //nob
    _nob->setShape(0.3*_width, 0.8*_height);
    _nob->setBackgroundColor(0.0f, 0.0f, 0.0f, 1.0f);
    _nob->setBorderColor(0.5f, 0.5f, 0.5f, 0.8f);
    _nob->setPivot(0.5*_nob->getWidth(), 0.5*_nob->getHeight(), 0.f);
    //nob->setPosition(0.5*width, 0.5*height, 0.0);
    _nob->setPosition(0.5*_width, 0.5*_height, 0.0);
    
}

void SliderWidget::setName( std::string name ) {
    Widget::setName(name);
    _nob->setName(name);    
}


void SliderWidget::setLabelColor( float r, float g, float b, float a ) {
    _nob->setLabelColor(r,g,b,a);
}
    

// Frame Events
//
void SliderWidget::update() {
    /*
    if( velocity[0] > 0.00001 || velocity[1] > 0.00001 || velocity[2] > 0.00001 ) {
        velocity = velocity * 0.8;
        //addPosition(velocity);
    } else {
        velocity.set(0,0,0);
    }
    */
    
    //static float ang = 0.0f;
    //addZ(1);
    //addRotationX(3.14/200);
}


void SliderWidget::addEventHandler( SliderHandler* handler ){
    _handlers.push_back( handler );
}

std::vector<SliderHandler*>&  SliderWidget::getEventHandlers() {
    return _handlers;
}


// Touch Events
//
bool SliderWidget::touchDown( Touch& touch ) {
    return true;
}  
bool SliderWidget::touchMove( Touch& touch ) {
    if( isDragging(touch) ) {
        addPosition(getWorldDragDelta(touch));
    }
    
    for( unsigned int i=0; i<_handlers.size(); i++) {
        _handlers[i]->widgetSlider( *this );  //should be slider not nob
    }              
    
    return true;
}
bool SliderWidget::touchUp( Touch& touch ) {
    return true;
}


